package com.lhz.log;

import com.lhz.JobApplicationContext;
import com.lhz.model.constant.RunnableConstant;
import com.lhz.model.entity.JobInfo;
import com.lhz.model.entity.JobLog;
import com.lhz.service.LogService;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author: LiHuaZhi
 * @Date: 2021/8/14 16:48
 * @Description:
 **/
@Slf4j
public class JobLogRecord {

    private final static Map<Long, StringBuffer> LOG_MSG = new ConcurrentHashMap<>();
    private final static Map<Long, Long> LOG_TIME = new ConcurrentHashMap<>();
    private final static Map<Long, String> LOG_STATE = new ConcurrentHashMap<>();
    private final static String BR = "<br>\n";
    private final static String FAIL = " [failure] ";
    private final static String SUCCESS = " [success] ";
    private final static DateTimeFormatter DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    private final static String FAIL_STATE = "fail";
    private final static String SUCCESS_STATE = "success";

    /**
     * 异步写入数据库
     */
    private static LogService logService = JobApplicationContext.getBean(LogService.class);

    /**
     * 初始化日志
     *
     * @param jobId
     * @param jobName
     * @param address
     * @param executorHandler
     * @param executorParam
     */
    public static void init(Long jobId, String jobName, String address, String executorHandler, String executorParam) {
        // 开始时间
        long startTime = System.currentTimeMillis();
        LOG_TIME.put(jobId, startTime);
        LOG_STATE.put(jobId, SUCCESS_STATE);

        StringBuffer sb = LOG_MSG.get(jobId);
        if (sb == null) {
            sb = new StringBuffer();
        }
        String time = DTF.format(LocalDateTime.now());
        sb.append(time).append(SUCCESS).append("-----------job execute start ----------").append(BR)
                .append(time).append(SUCCESS).append("任务ID：").append(jobId).append(BR)
                .append(time).append(SUCCESS).append("任务名称：").append(jobName).append(BR)
                .append(time).append(SUCCESS).append("任务参数：").append(executorParam).append(BR)
                .append(time).append(SUCCESS).append("执行Bean对象：").append(executorHandler).append(BR);

        LOG_MSG.put(jobId, sb);
    }

    public static void success(Long jobId, String msg) {
        String time = DTF.format(LocalDateTime.now());
        StringBuffer sb = getMap(jobId);
        sb.append(time).append(SUCCESS).append(msg).append(BR);
    }


    public static void fail(Long jobId, String msg) {
        LOG_STATE.put(jobId, FAIL_STATE);
        String time = DTF.format(LocalDateTime.now());
        StringBuffer sb = getMap(jobId);
        sb.append(time).append(FAIL).append(msg).append(BR);
    }


    /**
     * 结束任务
     *
     * @param jobId
     */
    public static void end(Long jobId) {
        String time = DTF.format(LocalDateTime.now());

        long startTime = LOG_TIME.get(jobId);
        // 结束时间
        long endTime = System.currentTimeMillis();
        // 耗时(s)
        double useTime = (endTime - startTime) / 1000.00;

        StringBuffer sb = getMap(jobId);
        sb.append(time).append(SUCCESS).append("耗时：").append(useTime).append("S").append(BR);
        sb.append(time).append(SUCCESS).append("-----------job execute end ----------").append(BR);

        // 封装数据异步写入到数据库
        insertLog(jobId, sb.toString(), useTime);

        // 清空map
        LOG_STATE.remove(jobId);
        LOG_MSG.remove(jobId);
        LOG_TIME.remove(jobId);
    }

    private static void insertLog(Long jobId, String msg, double useTime) {
        JobInfo jobInfo = RunnableConstant.JOB_MAP.get(jobId);
        JobLog jobLog = new JobLog();
        jobLog.setJobId(jobInfo.getId());
        jobLog.setExecutorHandler(jobInfo.getExecutorHandler());
        jobLog.setExecutorParam(jobInfo.getExecutorParam());
        jobLog.setHandleState(LOG_STATE.get(jobId));
        jobLog.setHandleMsg(msg);
        jobLog.setHandleTime(useTime);
        jobLog.setExecutorAddress(RunnableConstant.EXECUTOR_ADDRESS);

        logService.insertLog(jobLog);
    }

    private static StringBuffer getMap(Long jobId) {
        String time = DTF.format(LocalDateTime.now());
        StringBuffer buffer = LOG_MSG.get(jobId);
        if (buffer == null) {
            buffer = new StringBuffer();
            buffer.append(time).append(FAIL).append("没有初始化日志记录").append(BR);
        }
        return buffer;
    }
}
